home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-19 | 7.8 KB | 181 lines | [TEXT/ttxt] |
- DTS sample RAM disk. Originally by Gordon Sheridan. Updated by Jim Luther.
- Metrowerks conversion by Brian Bechtel, DTS 940519 at the WWDC (Thanks to
- the Metrowerks coding lab.) 1.2 update on vacation in Kauai, which says
- something about me which I'd really not rather examine right now...
-
- This sample is a control panel, which installs a RAM disk. Under Metrowerks
- and Symantec, this sample is completely in C.
-
- How I converted this program from MPW to Metrowerks.
-
- • Added a main() routine to the driver to handle Metrowerks' startup code.
- • Cleaned up various errors or warnings where Metrowerks was tighter than
- MPW or Symantec.
- • Created a project file for the control panel. This project creates a
- code resource of type cdev, id -4064, which is a control panel. This
- project file is '3RamCDEV.µ'.
- • I built the resource file, and named it '3RamCDEV.µ.rsrc'. This ensures
- that the resources will be automatically included when you build the
- control panel.
- • Created a project file for the DRVR. This project is a code resource
- of type DRVR, id 48, which is the driver itself. Set the project so
- that the DRVR resource is merged into '3RamCDEV.µ.rsrc'.
- • Created a project file for the INIT. This project is a code resource
- of type INIT, id 0, which will install the driver. Set the project so
- that the INIT resource is merged into '3RamCDEV.µ.rsrc'.
- • I had to change the code slightly, because this driver was using some
- low memory globals directly. I now handle low memory accesses by using
- accessor functions. There was one problem; UnitNTryCnt was not defined.
- I created my own accessor functions for this low memory global. This is
- fixed in the Universal Headers starting with ETO 15.
- • Recalculate BufPtr from the low memory global.
-
- There is no way to set the driver flags in the driver header. You have
- to either use ResEdit to change them to the desired values, or set them
- explicitly in the driver. This sample driver sets the flags directly,
- in the DRVROpen() routine.
-
- Build Order
-
- The control panel consists of four parts: various resources needed to
- run, plus an 'INIT' to load the driver, a 'DRVR' which is the driver
- itself, and a 'cdev' which is the user interface for setting up the
- driver.
-
- If you are using the .r file, use MPW or SARez to build the resource
- file RamCDev.µ.rsrc. All three projects assume the existence of
- 3RamCDev.µ.rsrc
-
- Build the project 1RamINIT.µ. This will add an 'INIT' resource to
- 3RamCDev.µ.rsrc.
-
- Build the project 2RamDRVR.µ. This will add a 'DRVR' resource to
- 3RamCDev.µ.rsrc.
-
- Build the project 3RamCDEV.µ. This will create a control panel
- containing the 'INIT', 'DRVR', and 'cdev' resources necessary to run
- this control panel.
-
- You can use the AppleScript provided to build either the Metrowerks or
- Symantec versions of this RAMDisk.
-
- Known errors in Metrowerks:
-
- MW C/C++ 68K 1.0 & earlier: The driver name ".RamDRVR" is put into the
- driver as {09}{00}.RamDRVR. I had to change this to {08}.RamDRVR{00}
- to be correct. This is what it should have generated. Use ResEdit.
- This is fixed in MW C/C++ 68K 1.0.1.
-
- Version History:
-
- 1.0 First release
-
- 1.1 In the file RAMInit.c, in the procedure GrowUnitTable(), there was
- a line which read:
- newUnitTableBase = NewPtrSysClear(sizeof(newUnitEntryCount * sizeof(long)));
- this line should be
- newUnitTableBase = NewPtrSysClear(newUnitEntryCount * sizeof(long));
- Because of this bug, trying to grow the unit table will overwrite other
- parts of the system heap and potentially crash. Thanks to Mike Wiese
- for finding this bug.
-
- 1.2 Fixed several issues in RAMInit.c:
-
- • DriverInstall (suggested by John Wang)
- Instead of creating a AuxDCE record, we were creating a DCtlEntry.
- Because the record is smaller, the dCtlSlot field is garbage and causes
- _SUpdateSrt to be called when the driver is closed.
-
- • DriverRemove (suggested by Mike Wiese)
- DriverRemove should not be disposing the driverhandle stored in
- dCltDriver, since the install routine calls ReleaseResource or
- DisposHandle as appropriate. Plus, if it's pointer based as it should
- be, disposeHandle won't work.
-
- • DriverInstall (suggested by François Grieu)
- The Sample RAMDisk is installed with the dRamBased bit set. Therefore,
- calls to this driver cause the DCtlEntry to be passed to _RecoverHandle
- and _HLock, and the driver's code Handle to _HLock. Doing this is
- illegal at interrupt time, because the Memory Manager is not reentrant.
- Most noticeably, a foreground app relying on MemError() stands a risk
- to miss errors when the shared RAMdisk is remotely accessed, or if a
- sound is playing from a file on the RAMdisk (using SndStartFilePlay),
- because each access to the RAMdisk clears the global MemErr.
-
- By contrast, physical disks (and AppleShare) drivers are installed with
- the dRamBased bit clear, which makes them immune to this particular
- problem.
-
- The solution is to modify how the driver is installed : clear the
- dRamBased bit in the dCtlFlags field of the DCtlEntry, and change the
- dCtlDriver field from a Handle to a Pointer; also the DCtlEntry must be
- locked. I tried this for using a debugger and is fixes the problem.
- As an aside benchmarks of the emulated disk are noticeably improved.
-
- • DriverInstall
- DriverInstall changed to myDriverInstall. Universal Headers 2.0 now
- contains a definition for DriverInstall, and we don't want to create
- confusion in naming.
-
- • DriverRemove
- DriverRemove changed to myDriverRemove. Universal Headers 2.0 now
- contains a definition for DriverRemove, and we don't want to create
- confusion in naming.
-
- • GetUnusedDrvrRefNum (suggested by Matthew E. Axsom)
- The problem occurs in the following lines of code:
-
- > while ((unitTable[unitNumber] != nil) && (unitNumber < unitEntryCount))
- > ++unitNumber;
- >
- > if (unitTable[unitNumber] == nil) /* Find an empty entry? */
- > /* Yes, then calculate its driver reference number */
- > drvrRefNum = -1 * (unitNumber +1);
-
- The above code works just fine as long as the unit table has at least 1
- empty slot in it. If the unit table is completely full, i.e., no empty
- slots then this section of code can produce an invalid drvrRefNum. I
- believe that if the table is full that the routine should return 0
- (zero) and then grow the unit table and try again. Instead, here's
- what can happen if the unit table is completely full:
-
- If there are no empty slots in the unit table then eventually unitNumber
- will be >= unitEntryCount and the 'while' loop will terminate with
- unitNumber equal to unitEntryCount. Since there are only
- unitEntryCount-1 entries in the unit table, unitNumber now contains an
- "out of bounds" index for the unit table. After falling out of the
- 'while' loop, the 'if' statement then uses the "out of bounds"
- unitNumber for indexing into unitTable. At this point if the address
- pointed to by unitTable[unitNumber] is nil then we get a "valid"
- drvrRefNum which is really invalid because unitNumber is "out of
- bounds". What should happen is that the table is full and a drvrRefNum
- of 0 (zero) be returned so the unit table can be grown.
-
- Since I needed to load a driver, I corrected the code this way:
-
- > while (unitNumber < unitEntryCount) {
- > if (unitTable[unitNumber] == nil) { /* Find an empty entry? */
- > /* Yes, then calculate its driver reference number */
- > drvrRefNum = -1 * (unitNumber +1);
- > break;
- > }
- > else
- > ++unitNumber;
- > }
-
- I tested this out and, as far as I can tell, it works. It correctly
- detects a full unit table and returns 0. The calling routine then
- grows the unit table and tries again, this time with success.
-
- • GetUnitEntryCount
- Changed to use new definition in Universal Headers 2.0.
-
- • SetUnitEntryCount
- Changed to use new definition in Universal Headers 2.0.
-
- • All three Metrowerks Projects
- I added the keyword STR# resource from "Toasty's Keyword Resources",
- which can be found on the Internet at sumex-aim.stanford.edu and
- various other online services. This new STR# gives highlighting to
- all Apple defined keywords. (Default is green)
-